package com.joey.gateway.filter;

import com.joey.common.context.UserContext;
import com.joey.gateway.config.AuthProperties;
import com.joey.gateway.config.JwtProperties;
import com.joey.gateway.util.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * @author: Joey
 * @Description:
 * @date:2024/6/22 21:46
 */
@Component
@RequiredArgsConstructor
@EnableConfigurationProperties(AuthProperties.class)
@Slf4j
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    private final JwtProperties jwtProperties;
    private final AuthProperties authProperties;
    //spring匹配器
    private final AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        if(isExclude(request.getPath().toString())){
            // 无需拦截，直接放行
            return chain.filter(exchange);
        }
        List<String> headers = request.getHeaders().get(jwtProperties.getUserTokenName());
        String token = null;
        if(headers !=null && !headers.isEmpty()){
            token = headers.get(0);
        }
        Long userId=null;
        try {
                Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);
                userId = Long.valueOf(claims.get("userId").toString());
        } catch (Exception e) {
            log.error("jwt校验失败");
            log.error(String.valueOf(e));
            ServerHttpResponse response = exchange.getResponse();
            response.setRawStatusCode(401);
            return response.setComplete();
        }
        Long uid = userId;
        UserContext.setCurrentId(userId);//存入当前线程内
        ServerWebExchange ex = exchange.mutate()
                .request(b-> b.header("user-info",uid.toString())).build();
        System.out.println("jtw to pass currentID:"+userId);
        return chain.filter(ex);
    }
    //排除不需要过滤路由
    private boolean isExclude(String antPath) {
        for (String pathPattern : authProperties.getExcludePaths()) {
            if(antPathMatcher.match(pathPattern, antPath)){
                return true;
            }
        }
        return false;
    }

    @Override
    public int getOrder() {
        return 0;
    }


    // 在登录时 redis存放 => redisTemplate.opsForValue().set("tk" + userId, user,60, TimeUnit.MINUTES);
    // 使用redis做校验
    //  Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
    //            Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
    //String redisKey = "tk" + userId;
    //        UserDT user = (UserDT) redisTemplate.opsForValue().get(redisKey);

    ////        续期 离过期时间只有20分钟时才更新过期时间
    //        if ( redisTemplate.opsForValue().getOperations().getExpire(redisKey) < 1 * 60 * 20) {
    //            redisTemplate.opsForValue().set("tk" + userId, user,60, TimeUnit.MINUTES);
    //            log.error("update token info, id is:{}, user info is:{}", user.getUser().getId(), user.getUser());
    //        }
}
